Baner
; В начало ; Новости ; Теория ; Ресурсы ; Ссылки ; Форум ; Почта ;
Математика и физика
2D графика

   DirectDraw:
3D графика

   OpenGL:
Rambler's Top100 Rambler's Top100
RayTrace тени.
Тени - необходимый аттрибут любой реалистичной игры. Есть несколько способов создавать тени. В этой главе будет рассказано о том как создать тени путем трасировки лучей. Вероятно, это не самый шустрый способ, но качество и реалистичнось получающихся теней наивысши.

Итак, о том что же такое RayTrace. RaytraceMethod Это тип расчетов, при которых от источника к каждой вершине объекта проводится луч, далее исчется пересечение этих лучей с нужной плоскостью. В нашем случае источником является лампочка, солнце или какой-нибудь другой источник света, объектом является тело, отбрасывающее тень, а плоскость является поверхность на которрую отбрасывается тень. Далее все точки пересечения лучей и плоскости соединяются - тень от одного полигона получена. Итак, как же все это выглядит на практике. Я написал функцию, которая отбрасывает тени от объектов, состоящих из треугольников:

void CClassGraphic::CastShadow(GLfloat aVertex[][3],
			        UINT nCount,
			        const CPlane &pl,
			        const CVertex& LightPos)
{
	BOOL i1, i2, i3;
	CVertex a, b, c;
	CVertex	v1, v2, v3;
	glDisable(GL_DEPTH_TEST);
		
	glColor4f(0,0,0, 0.5f);
	for (UINT i=0; i<nCount; i++)
	{
		v1.x = aVertex[3*i][0];
		v1.y = aVertex[3*i][1];
		v1.z = aVertex[3*i][2];
		i1 = pl.LineIntersect(LightPos, v1, LT_RAY, &a);

		v2.x = aVertex[3*i+1][0];
		v2.y = aVertex[3*i+1][1];
		v2.z = aVertex[3*i+1][2];
		i2 = pl.LineIntersect(LightPos, v2, LT_RAY, &b);

		v3.x = aVertex[3*i+2][0];
		v3.y = aVertex[3*i+2][1];
		v3.z = aVertex[3*i+2][2];
		i3 = pl.LineIntersect(LightPos, v3, LT_RAY, &c);

		if (i1 && i2 && i3)
		{
			glBegin(GL_TRIANGLES);
				glVertex3f(a.x, a.y, a.z);
				glVertex3f(b.x, b.y, b.z);
				glVertex3f(c.x, c.y, c.z);
			glEnd();
		}
	}
	glEnable(GL_DEPTH_TEST);
}
Думаю все понятно, но на всякий случай приведу некоторые пояснения. Параметры функции соответственно: масив вершин объекта, количество треугольников в объекте, плоскость, на которую отбрасывается тень, и позиция источника света. С помощью функции glColor4f можно менять густоту тени: чем больше непрозрачность, те гуще тень. Далее расчитываются точки a, b и c, которые являются точками пересечения лучей и плоскости. Затем если все лучи пересекли плоскость, прорисовываем тень.

Как вы могли заметить, у этого способа есть определенные недостатки. Тень появляется лишь если все лучи пересекают плоскость. Статья об универсальных тенях будет написана отдельно. Хотя описанный здесь способ подходит для 90% случаев.

Примечание №1: Если вы не уверенны в том что тень полностью будет лежать на поверхности используйте буффер трафарета, так же, как и в главе о плоских зеркалах.
Примечание №2: Можно придать тени некоторую размытость, если по контуру провотить линии со включеным Antialias'ингом. Главное следите за тем чтобы цвета тени и контура совпадали.


ShadowDemo Не обошлось без демки. Это демонстрашка солнечных часов, которая использует RayTrace тени.

Cкачать демку.[63 Kb]
Cкачать исходники.[80 Kb]

Используются технологии uCoz